home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / uucp106d / part11 < prev    next >
Encoding:
Internet Message Format  |  1990-06-28  |  36.6 KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i189: UUCP 1.06D - UNIX compatible uucp/news/mail system, Part11/12
  5. Message-ID: <12980@xanth.cs.odu.edu>
  6. Date: 28 Jun 90 12:23:40 GMT
  7. Sender: news@cs.odu.edu
  8. Reply-To: Matt Dillon <@uunet.uu.net:overload!dillon>
  9. Lines: 1532
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon>
  15. Posting-number: Volume 90, Issue 189
  16. Archive-name: unix/uucp-1.06d/part11
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 11 (of 12)."
  25. # Contents:  uucp2/src/uucico/uucico.c
  26. # Wrapped by tadguy@xanth on Thu Jun 28 08:21:37 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'uucp2/src/uucico/uucico.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'uucp2/src/uucico/uucico.c'\"
  30. else
  31. echo shar: Extracting \"'uucp2/src/uucico/uucico.c'\" \(33705 characters\)
  32. sed "s/^X//" >'uucp2/src/uucico/uucico.c' <<'END_OF_FILE'
  33. X
  34. X/*
  35. X *  UUCICO.C
  36. X *
  37. X *  $Header: Beta:src/uucp/src/uucico/RCS/uucico.c,v 1.1 90/02/02 11:56:01 dillon Exp Locker: dillon $
  38. X *
  39. X *  (C) Copyright 1987 by John Gilmore.
  40. X *  Copying and use of this program are controlled by the terms of the Free
  41. X *  Software Foundation's GNU Emacs General Public License.
  42. X *
  43. X *  Derived from:
  44. X *  i[$]uuslave.c     1.7 08/12/85 14:04:20
  45. X *  which came from the ACGNJ BBS system at +1 201 753 9758.  Original
  46. X *  author unknown.
  47. X *
  48. X *  Ported to Amiga by William Loftus
  49. X *  Amiga Changes Copyright 1988 by William Loftus.  All rights reserved.
  50. X *  Additional Major Changes (c)Copyright 1989 by Matthew Dillon, All rights reserved
  51. X *
  52. X * 14-Oct-89, moved modem_init() to before poll_sys.
  53. X *
  54. X * -r option       (-r1 does a call out to all systems we have mail for)
  55. X * -D[EVICE] dev    sets serial device name (automatic from Getty)
  56. X * -U[NIT] unit     sets unit name (automatic from Getty)
  57. X * -h0            Ignore CD (carrier detect)
  58. X * -7
  59. X */
  60. X
  61. X
  62. X#include "includes.h"           /* System include files, system dependent */
  63. X#include "uucp.h"               /* Uucp definitions and parameters */
  64. X#include <log.h>
  65. X#include "version.h"
  66. X
  67. XPrototype   int getname(int);
  68. XPrototype   int get_proto(void);
  69. XPrototype   int instr(char *, int);
  70. XPrototype   int twrite(const char *, int);
  71. XPrototype   void xlat_str(char *, char *);
  72. XPrototype   int read_ctl(void);
  73. XPrototype   int do_outbound(void);
  74. XPrototype   int call_system(char *, int);
  75. XPrototype   int call_sysline(char *);
  76. XPrototype   int do_session(int);
  77. XPrototype   int top_level(int);
  78. XPrototype   int do_one_slave(void);
  79. XPrototype   int do_one_master(void);
  80. XPrototype   int yesno(char, int, int);
  81. XPrototype   int host_send_file(char *);
  82. XPrototype   int host_receive_file(char *);
  83. XPrototype   int local_send_file(char *, int *);
  84. XPrototype   int local_receive_file(void);
  85. XPrototype   int receive_file(FILE *, char *, char *, char *, int);
  86. XPrototype   int send_file(FILE *);
  87. X
  88. X#define MAX_FLAGS    40
  89. X
  90. Xextern int errno;
  91. X
  92. XIDENT(".10");
  93. X
  94. Xstatic char *Copyright = COPYRIGHT;
  95. X
  96. Xchar    ttynam[NAMESIZE],        /* Name of tty we use as serial port */
  97. X    srcnam[NAMESIZE],        /* Source file name */
  98. X    dstnam[NAMESIZE],        /* Dest file name */
  99. X    who[NAMESIZE] = "-",            /* Who sent the file */
  100. X    flags[MAX_FLAGS],        /* Flags from file xfer cmd */
  101. X    temp[NAMESIZE];         /* Temp file name */
  102. X
  103. Xint    ourpid = 0,            /* Our process ID */
  104. X    ignore_time_restrictions = 0,    /* Call out even if L.sys sez no */
  105. X    mode;                /* File mode from file xfer cmd */
  106. X
  107. Xchar  host_name[MAX_HOST] = "AmigaUUCP";  /* Other guy's host name */
  108. Xchar  our_name[MAX_HOST];    /* Our uucp hostname, set from usenet.ctl */
  109. Xchar  path[128];
  110. Xint   debug   = -1;    /* -1 indicates not set by command line or ctl file */
  111. Xint   f_wait  = 0;    /* wait for a call (-w) or calls (-w -e) after outbnd */
  112. Xint   loop    = 0;    /* Loop accepting logins if tty name specified */
  113. Xint   curtemp = 0;
  114. Xint   Overide = 0;    /* overide modem protocol        */
  115. Xint   Getty   = 0;    /* -Getty initiated            */
  116. Xint   IgnoreCD= 0;    /* xgetc() should ignore carrier?   */
  117. Xint   OurNameOv= 0;
  118. Xint   WindowOne= 0;
  119. Xint   SevenWire= 0;
  120. Xint   XDebug  = 0;    /* do not pass debug parameter to remote    */
  121. X
  122. X#define MAX_STRING    200    /* Max length string to send/expect */
  123. X
  124. X#define MSGO2IDX    7
  125. X
  126. X/* We print these prompts */
  127. X
  128. Xchar msgo0[] = "login: ";
  129. Xchar msgo1[] = "Password:";
  130. Xchar msgo2[10+MAX_HOST] = { "\20Shere" };   /*  NO =    */
  131. Xchar msgo3[] = "\20ROK\0";
  132. Xchar msgo3a[]= "\20P";
  133. Xchar msgo3b[]= "\20Pg\0";
  134. Xchar msgo4[] = "\20OOOOOOO\0";
  135. X
  136. X/* We expect to receive these strings */
  137. X
  138. Xchar msgi0[] = "uucp\r";
  139. Xchar msgi1[] = "s8000\r";
  140. X/* char msgi2[] = "\20S*\0"; We now scan it specially FIXME */
  141. Xchar msgi3[] = "\20Ug\0";
  142. Xchar msgi4[] = "OOOOOO";
  143. X
  144. X/*
  145. X * Protocol switch data structure
  146. X */
  147. X
  148. X#define turnon    gturnon
  149. X#define rdmsg    grdmsg
  150. X#define wrmsg    gwrmsg
  151. X#define rddata    grddata
  152. X#define wrdata    gwrdata
  153. X#define turnoff gturnoff
  154. X
  155. Xint
  156. Xgetname(isshere)
  157. Xint isshere;
  158. X{
  159. X    int data, count = 0;
  160. X    static char msgi[MAX_STRING+SLOP];    /* Incoming trash buffer */
  161. X
  162. X    /* Read data until null character */
  163. X
  164. X    while ((data = xgetc(BYTE_TO)) != EOF) {
  165. X    data &= 0x7F;
  166. X    if (data == 020)
  167. X        break;
  168. X    }
  169. X    if (data == EOF)
  170. X    return FAIL;
  171. X
  172. X    while ((data = xgetc(BYTE_TO)) != EOF && (data & 0x7F)) {
  173. X    data &= 0x7F;
  174. X    if (count == 0 && data != 'S')
  175. X        continue;
  176. X    if (count > sizeof(msgi) - 2)
  177. X        continue;
  178. X    msgi[count++] = (char)data;
  179. X    }
  180. X    msgi[count] = 0;
  181. X
  182. X    if (debug > 8)
  183. X    printf("GETNAME MSG (%d): %s\n", count, msgi);
  184. X
  185. X    if (msgi[0] != 'S')
  186. X    return FAIL;
  187. X    if (isshere) {
  188. X    for (count = 1; msgi[count] && msgi[count] != '='; ++count);
  189. X    if (msgi[count] == '=')
  190. X        ++count;
  191. X    } else {
  192. X    count = 1;
  193. X    }
  194. X    if (msgi[count]) {
  195. X    if (debug > 8)
  196. X        printf("Compare host names: '%s' '%s'\n", host_name, msgi + count);
  197. X    strcpy (host_name, msgi + count);
  198. X    }
  199. X    strtok(host_name, " \t");     /*  put \0 after hostname */
  200. X    if (debug > 8)
  201. X    printf("Hostname is '%s'\n", host_name);
  202. X    return SUCCESS;
  203. X}
  204. X
  205. X/*
  206. X *  get_proto() checks the list of protos given by the foriegn machine
  207. X *  checking for 'g' (which is the only proto we have).  Use only in master
  208. X *  mode.
  209. X */
  210. X
  211. Xint
  212. Xget_proto()
  213. X{
  214. X    int data;
  215. X
  216. X    while ((data = xgetc(BYTE_TO)) != EOF) {
  217. X    data &= 0x7F;
  218. X    if (data == 0)
  219. X        break;
  220. X    if (data == 'g')
  221. X        return(SUCCESS);
  222. X    }
  223. X    return FAIL;
  224. X}
  225. X
  226. X/*
  227. X * Medium level input routine.
  228. X *
  229. X * Look for an input string for the send-expect sequence.
  230. X * Return 0 for matching string, 1 for timeout before we found it.
  231. X * FIXME:  we only time out if the other end stops sending.  If it
  232. X *       keeps sending, we keep listening forever.
  233. X */
  234. X
  235. Xinstr(s, n)
  236. Xchar *s;
  237. Xint n;
  238. X{
  239. X    int data,count,j;
  240. X    int i;
  241. X    static char msgi[512];  /* Incoming trash buffer */
  242. X
  243. X    count = 0;
  244. X
  245. X    if (debug > 8) {
  246. X    printf("Expecting ");
  247. X    for (i = 0; i < n; i++)
  248. X        printc(s[i]);
  249. X    printf("\n");
  250. X    }
  251. X
  252. X    while ((data = xgetc(BYTE_TO)) != EOF) {
  253. X    msgi[count++] = (char)data & 0x7F;
  254. X
  255. X    if (count == sizeof(msgi)) {    /*  throw away first half */
  256. X        count = sizeof(msgi) / 2;
  257. X        bcopy(msgi + sizeof(msgi) / 2, msgi, sizeof(msgi) / 2);
  258. X    }
  259. X
  260. X    if (count >= n) {
  261. X        for (i = n - 1, j = count - 1; i >= 0; i--, j--) {
  262. X        if (*(s+i) != msgi[j])
  263. X            break;
  264. X        }
  265. X        if (i < 0) {
  266. X        if (debug > 8)
  267. X            printf("\n");
  268. X        return(0);
  269. X        }
  270. X    }
  271. X    }
  272. X
  273. X    if (debug > 8)
  274. X    printf("\n");
  275. X    msgi[count] = (char)0;
  276. X    return(1);
  277. X}
  278. X
  279. X/*
  280. X * Debugging hack for stuff written to the modem.
  281. X */
  282. X
  283. Xint
  284. Xtwrite(s, n)
  285. Xconst char *s;
  286. Xint  n;
  287. X{
  288. X    int i;
  289. X
  290. X    if (debug > 8) {
  291. X    printf("Wrote:  ");
  292. X    for (i = 0; i < n; i++)
  293. X        printc(s[i]);
  294. X    printf("\n");
  295. X    }
  296. X    return xwrite(s, n);
  297. X}
  298. X
  299. X/*
  300. X * MAIN ROUTINE.
  301. X *
  302. X * This is called at program startup.  It parses the arguments to the
  303. X * program (if any) and sets up to receive a call on the modem.
  304. X *
  305. X * If there are no arguments, we assume the caller is already on standard
  306. X * input, waiting to do uucp protocols (past the login prompt), and we
  307. X * just handle one caller.
  308. X *
  309. X * If there is an argument, it is the name of the tty device where we
  310. X * should listen for multiple callers and handle login and password.
  311. X */
  312. X
  313. Xvoid
  314. Xmain(argc,argv)
  315. Xint argc;
  316. Xchar *argv[];
  317. X{
  318. X    int     i;
  319. X    char    *poll_sys = (char *)NULL;   /* System name to poll, or none */
  320. X    short   rmode = 0;            /* 1 = master, 0 = slave    */
  321. X
  322. X    LogProgram = "uucico";
  323. X    LogHost = host_name;
  324. X    LogWho  = who;
  325. X
  326. X    onbreak(sigint);
  327. X
  328. X    /* FIXME, use getopt */
  329. X    /* scan command line arguments, kinda kludgy but it works */
  330. X
  331. X    for (i = 1; i < argc; ++i) {
  332. X    if (argv[i][0] != '-') {
  333. X        printf("uucico: warning, extra args ignored: %s\n", argv[i]);
  334. X        break;
  335. X    }
  336. X    switch (argv[i][1]) {
  337. X    case 'N':
  338. X        strcpy(our_name, argv[i] + 2);
  339. X        OurNameOv = 1;
  340. X        break;
  341. X    case 'D':       /*  Serial Device   */
  342. X        {
  343. X        extern char *DeviceName;
  344. X        DeviceName = argv[++i];
  345. X        }
  346. X        break;
  347. X    case 'U':       /*  Serial Unit     */
  348. X        {
  349. X        extern long DeviceUnit;
  350. X        DeviceUnit = atoi(argv[++i]);
  351. X        }
  352. X        break;
  353. X    case 'g':
  354. X    case 'G':
  355. X        Getty = 1;
  356. X        break;
  357. X    case 'h':
  358. X        IgnoreCD = atoi(argv[i] + 2);
  359. X        break;
  360. X    case 'w':
  361. X        ++f_wait;
  362. X        break;
  363. X    case 'r':
  364. X        rmode = atoi(&argv[i][2]);
  365. X        break;
  366. X    case 'X':
  367. X        XDebug = 1;
  368. X    case 'x':
  369. X        debug = atoi(&argv[i][2]);
  370. X        LogLevel = debug;
  371. X        LogToStdout = 1;
  372. X        printf("uucico: debug level set to %d\n", debug);
  373. X        break;
  374. X    case 'o':
  375. X        Overide = 1;
  376. X        break;
  377. X    case 'n':
  378. X        WindowOne = 1;  /*    force windowing mode to size=1     */
  379. X        break;
  380. X    case 'S':
  381. X        ignore_time_restrictions++;
  382. X    case 's':
  383. X        poll_sys = &argv[i][2];
  384. X        break;
  385. X    case 'e':
  386. X        ++loop;
  387. X        break;
  388. X    /* Is -t needed for MSDOS?  Why?  -- hoptoad!gnu */
  389. X    case 't':
  390. X        curtemp++;
  391. X        printf("uucico: using ~uutemp.$$$ for temp file\n");
  392. X        break;
  393. X    case '7':
  394. X        SevenWire = 1;
  395. X        break;
  396. X    default:
  397. X        printf("uucico: warning, bad flag %s\n", argv[i]);
  398. X        break;
  399. X    }
  400. X    }
  401. X
  402. X    /* If argument provided, use it as name of comm port */
  403. X
  404. X    /* FIXME, this needs some thought. */
  405. X
  406. X    getcwd(path,128);
  407. X    if (chdir(GetConfigDir(UUSPOOL))) {
  408. X    perror("Can't chdir to Spool directory");
  409. X    exit(2);
  410. X    }
  411. X
  412. X    read_ctl();
  413. X
  414. X    /*
  415. X     * If running via getty/login, our debug stdout had better
  416. X     * go to a file, not to the usual stdout!
  417. X     */
  418. X
  419. X    if (debug > 0 && Getty) {
  420. X    freopen("T:uuslave.log", "a", stdout);
  421. X    }
  422. X
  423. X    /*setvbuf(stdout, NULL, _IOLBF, 0);*/
  424. X
  425. X    /* Timestamp the long debug log */
  426. X
  427. X    if (debug > 0) {
  428. X    long clock;
  429. X
  430. X    time(&clock);
  431. X    printf("\014\nuuslave log on tty '%s' starting %s\n",
  432. X        ttynam, ctime(&clock));
  433. X    }
  434. X
  435. X    /* Log our presence so we humans reading the logs can find the
  436. X       entries created by uuslave. */
  437. X
  438. X    ulog(-1, "Startup %s", VERSION);
  439. X
  440. X    amiga_setup();
  441. X
  442. X    modem_init();
  443. X
  444. X    if (poll_sys) {
  445. X    if (*poll_sys == '\0')
  446. X        poll_sys = (char *)NULL;
  447. X    call_system(poll_sys, rmode);
  448. X    if (!f_wait)
  449. X        goto end;
  450. X    } else {
  451. X    if (rmode) {
  452. X        do_outbound();
  453. X        if (!f_wait)
  454. X        goto end;
  455. X    }
  456. X    }
  457. X
  458. X    do {
  459. X    /*
  460. X     *  Set up serial channel, wait for incoming call.
  461. X     */
  462. X    DEBUG(0, "\nRestarting\n", 0);
  463. X
  464. X    if (Getty == 0 && Overide == 0)
  465. X        openline();
  466. X
  467. X    do_session(Getty);
  468. X
  469. X    hangup();
  470. X    DEBUG(0, "\nEnd of call\n", 0);
  471. X    } while (loop && !Getty);
  472. X
  473. Xend:
  474. X    cleanup();
  475. X}
  476. X
  477. X/*
  478. X * translate embedded escape characters
  479. X */
  480. X
  481. Xvoid
  482. Xxlat_str(msg, out)
  483. Xchar    *msg;
  484. Xchar    *out;
  485. X{
  486. X    int i  = 0;
  487. X    int cr = 1;
  488. X    /*int j  = 0;*/
  489. X
  490. X    while (msg[i]) {
  491. X    if (msg[i] == '\\') {
  492. X        switch (msg[++i]) {
  493. X        case 'r':            /* carriage return */
  494. X        twrite("\r", 1);
  495. X        /*out[j++] = 0x0d;*/
  496. X        break;
  497. X        case 'n':            /* line feed */
  498. X        twrite("\n", 1);
  499. X        /*out[j++] = 0x0a;*/
  500. X        break;
  501. X        case '\\':           /* back slash */
  502. X        twrite("\\", 1);
  503. X        /*out[j++] = '\\';*/
  504. X        break;
  505. X        case 't':            /* tab */
  506. X        twrite("\t", 1);
  507. X        /*out[j++] = '\t';*/
  508. X        break;
  509. X        case 'b':
  510. X        SendBreak();
  511. X        break;
  512. X        case 'd':            /* delay */
  513. X        Delay(180);
  514. X        break;
  515. X        case 's':            /* space */
  516. X        twrite(" ", 1);
  517. X        /*out[j++] = ' ';*/
  518. X        break;
  519. X        case 'c':            /* no CR at end */
  520. X        cr = 0;
  521. X        break;
  522. X        default:        /* don't know so skip it */
  523. X        break;
  524. X        }
  525. X        ++i;
  526. X    } else {
  527. X        twrite(msg + i, 1);
  528. X        ++i;
  529. X        /*out[j++] = msg[i++];*/
  530. X    }
  531. X    }
  532. X    if (cr) {
  533. X    twrite("\r", 1);
  534. X    /*out[j++] = 0x0d;*/
  535. X    }
  536. X    /*out[j] = '\0';*/
  537. X}
  538. X
  539. X/*
  540. X * Read the control file and grab a few parameters.
  541. X */
  542. X
  543. Xint
  544. Xread_ctl()
  545. X{
  546. X    char *nodename = FindConfig(NODENAME);
  547. X    char *debugstr = FindConfig(DEBUGNAME);
  548. X
  549. X    if (nodename && OurNameOv == 0)
  550. X    strcpy(our_name, nodename);
  551. X    if (debugstr && debug < 0)
  552. X    debug = atoi(debugstr);
  553. X    return (1);
  554. X}
  555. X
  556. X/*
  557. X * Search spool queues for work, call the systems we need to call.
  558. X */
  559. X
  560. Xint
  561. Xdo_outbound()
  562. X{
  563. X    return call_system((char *)NULL, 1);
  564. X}
  565. X
  566. X/*
  567. X * Call a specific system, or all systems that have work pending.
  568. X */
  569. X
  570. Xint
  571. Xcall_system(sys, ifworkpend)
  572. Xchar    *sys;
  573. X{
  574. X    FILE    *lsys;
  575. X    static char buf[MAX_LSYS];
  576. X    static char sysnam[MAX_HOST];
  577. X    static char prev_name[MAX_HOST];
  578. X    int     called = FAIL;
  579. X
  580. X    /*
  581. X     * Unix uucico just reads the directory, and calls the systems
  582. X     * in the order of the files in the directory.  We want more
  583. X     * control than that, though I'm not sure that L.sys order is
  584. X     * best either.  For example, in the first call after 11PM,
  585. X     * I'd like to call the sites that haven't been callable before
  586. X     * 11PM first, and finish up with the ones I've been able to call
  587. X     * all day.  FIXME.
  588. X     */
  589. X
  590. X    if (! (lsys = fopen(MakeConfigPath(UULIB, "L.sys"), "r"))) {
  591. X    DEBUG(0, "uucico: can't open L.sys, errno %d\n", errno);
  592. X    return 0;
  593. X    }
  594. X    sysnam[0] = '\0';               /* Initially, no previous sys */
  595. X
  596. X    /* Once per system in L.sys... */
  597. X    /* FIXME, handle continuation lines (trailing "\") */
  598. X
  599. X    while (fgets(buf, sizeof buf, lsys)) {
  600. X    if (buf[0] == '#' || buf[0] == '\n')
  601. X        continue;
  602. X
  603. X    /*
  604. X     * Grab the system name.  If same as previous, and
  605. X     * the previous call worked, skip it.
  606. X     */
  607. X
  608. X    strcpy(prev_name, sysnam);
  609. X    (void) sscanf(buf, "%s", sysnam);
  610. X    if (!strcmp(sysnam, prev_name)) {
  611. X        if (called == SUCCESS)
  612. X        continue;
  613. X    }
  614. X
  615. X    /*
  616. X     * If a system name was specified, skip til we find it
  617. X     * If none was specified, only call if there is work.
  618. X     */
  619. X
  620. X    if (sys) {
  621. X        if (strcmp(sys, sysnam) != 0)
  622. X        continue;
  623. X        if (ifworkpend && !work_scan(sysnam)) {
  624. X        ulog(-1, "No work for system %s", sysnam);
  625. X        called = SUCCESS;
  626. X        continue;
  627. X        }
  628. X    } else {
  629. X        DEBUG(3,"searching for outbound to %s\n", sysnam);
  630. X        if (!work_scan(sysnam)) {
  631. X        DEBUG(3,"no work for %s\n", sysnam);
  632. X        called = SUCCESS;    /* Don't try further */
  633. X        continue;
  634. X        }
  635. X        DEBUG(2, "uucico: found work for %s\n", sysnam);
  636. X    }
  637. X
  638. X    called = call_sysline(buf);
  639. X
  640. X    if (called == SUCCESS && sys)
  641. X        break;
  642. X    }
  643. X
  644. X    fclose(lsys);
  645. X    if (called == FAIL && sys)
  646. X    DEBUG(0, "Could not call system %s\n", sys);
  647. X    return 0;
  648. X}
  649. X
  650. X/*
  651. X *  Call out to a system, given its L.sys line.
  652. X */
  653. X
  654. Xint
  655. Xcall_sysline(lsysline)
  656. Xchar *lsysline;
  657. X{
  658. X    static char    tempname[MAX_HOST + 30 + SLOP];
  659. X    static char    strbuf[MAX_STRING+SLOP];
  660. X    char    *sysnam,
  661. X        *times,
  662. X        *acu,
  663. X        *sbaud,
  664. X        *telno,
  665. X        *send,
  666. X        *expct;
  667. X    int     baud;
  668. X
  669. X    who[0] = '-'; who[1] = '\0';    /* No user now (for logit) */
  670. X
  671. X    /* FIXME, use the values it is ignoring here */
  672. X
  673. X    sysnam = strtok(lsysline, " \t");
  674. X    times =  strtok(NULL, " \t");   /* Time */
  675. X    acu =    strtok(NULL, " \t");   /* ACU  */
  676. X    sbaud =  strtok(NULL, " \t");   /* Baud */
  677. X    telno =  strtok(NULL," \t");    /* phone*/
  678. X
  679. X    strcpy(host_name, sysnam);
  680. X
  681. X    if (ignore_time_restrictions == 0) {
  682. X    if (CheckTimeRestrictions(times) == FAIL) {
  683. X        ulog(-1, "Wrong Time To Call %s", sysnam);
  684. X        return(FAIL);
  685. X    }
  686. X    }
  687. X
  688. X    baud = atoi(sbaud);
  689. X
  690. X    /*    FIX ME, acu not implemented ?    */
  691. X    DEBUG(4, "Opening outgoing line %s\n", acu);
  692. X    if (openout(acu, baud) != SUCCESS)
  693. X    return FAIL;
  694. X
  695. X    if (Overide == 0) {
  696. X    if (dial_nbr(telno)) {
  697. X        ulog(-1, "FAILED call to %s", host_name);
  698. X        return FAIL;
  699. X    }
  700. X    }
  701. X
  702. X    /* FIXME, log tty, baud rate, ... */
  703. X    ulog(-1, "DIALED %s", host_name);
  704. X
  705. X    /*
  706. X     * Process send-expect strings.
  707. X     * FIXME, deal with "-", BREAK, etc.
  708. X     */
  709. X
  710. X    while (send = (char*)strtok((char *)NULL, " \t")) {
  711. X    if (send[0] != '"' || send[1] != '"' || send[2] != '\0') {
  712. X        if (instr(send, strlen(send)))
  713. X            goto bort1;
  714. X    }
  715. X
  716. X    if (expct = (char*)strtok((char *)NULL, " \t")) {
  717. X        /* FIXME secondary strings, e.g. ogin:-EOT-ogin: */
  718. X        xlat_str(expct, strbuf);
  719. X
  720. X        /*twrite(strbuf, strlen(strbuf));*/
  721. X    }
  722. X    }
  723. X
  724. X    /*
  725. X     * FIXME, there should be a way to detect login/passwd
  726. X     * failure here and keep doing the script rather than
  727. X     * continuing to expect Shere at another login: prompt.
  728. X     */
  729. X
  730. X    ulog(-1, "SUCCEEDED call to %s", host_name);
  731. X
  732. X
  733. X    if (getname(1))         /*  get name        */
  734. X    goto bort1;
  735. X                /*    send response    */
  736. X    sprintf(tempname, "\20S%s -Q0 -x%d\0", our_name, (XDebug) ? 0 : debug);
  737. X    twrite(tempname, strlen(tempname)+1); /* Including null */
  738. X
  739. X    /* wait for ok message, wait for protocol request
  740. X     * send protocol 'g' response */
  741. X    /* FIXME, we don't actually wait for the ROK message, since
  742. X     * it is immediately followed by the Pprotos message.  We
  743. X     * currently just look for a Pg message.  This needs work.
  744. X     * FIXME, WE CAN'T TALK TO SITES THAT SUPPORT more than 'g'.
  745. X     */
  746. X
  747. X    if (instr(msgo3a, sizeof(msgo3a)-1)) {
  748. X    if (!get_proto())
  749. X       goto bort1;
  750. X    }
  751. X
  752. X
  753. X    twrite( msgi3, sizeof(msgi3)-1);
  754. X
  755. X    ResetGIO();                         /* reset GIO protocol   */
  756. X
  757. X    if (turnon(1))
  758. X    goto bort1;
  759. X
  760. X    ulog(-1, "OK Startup");
  761. X
  762. X    top_level(1);
  763. X    hangup();
  764. X    return SUCCESS;
  765. X
  766. Xbort1:
  767. X    hangup();
  768. X    return FAIL;
  769. X}
  770. X
  771. X/* Handle a single uucp [slave] login session */
  772. X
  773. Xint
  774. Xdo_session(ontheline)
  775. Xint ontheline;
  776. X{
  777. X    if (ontheline == 0) {
  778. X    /* output login request, verify uucp */
  779. X    twrite(msgo0,sizeof(msgo0)-1);
  780. X    if (instr(msgi0,sizeof(msgi0)-1)) {
  781. X        printf("uucico: invalid login name\n");
  782. X        goto bort;
  783. X    }
  784. X
  785. X    /* output password request, verify s8000 */
  786. X    twrite(msgo1,sizeof(msgo1)-1);
  787. X    if (instr(msgi1,sizeof(msgi1)-1)) {
  788. X        printf("uucico: invalid password\n");
  789. X        goto bort;
  790. X    }
  791. X
  792. X    printf("uucico: correct login\n");
  793. X    }
  794. X
  795. X    /*
  796. X     *    send Shere=<myhost>
  797. X     *
  798. X     *    Apparently mac UUCP has a bug that only allows 7
  799. X     *    char host names, and it fails if it gets shere=<myhost>
  800. X     *    where <myhost> is > 7 chars.
  801. X     */
  802. X
  803. X    /*strcpy(msgo2 + MSGO2IDX, our_name);*/
  804. X    twrite(msgo2,strlen(msgo2)+1);
  805. X
  806. X    /*
  807. X     *    get \020S<host> -Qn n    (??)
  808. X     */
  809. X
  810. X    if (getname(0))
  811. X    goto bort;
  812. X
  813. X    /* output ok message, output protocol request, wait for response */
  814. X
  815. X    twrite(msgo3,sizeof(msgo3)-1);
  816. X
  817. X    /* FIXME, make the protocol list here, and use it */
  818. X    twrite(msgo3b,sizeof(msgo3b)-1);
  819. X    if (instr(msgi3,sizeof(msgi3)-1))
  820. X        goto bort;
  821. X
  822. X    ResetGIO();                         /* reset GIO protocol   */
  823. X
  824. X    if (turnon(0))
  825. X    goto bort;
  826. X
  827. X    ulog(-1, "OK Startup");
  828. X    top_level(0);
  829. X
  830. Xbort:
  831. X    if (debug > 0)
  832. X    printf("uucico: call complete\n");
  833. X    return (1);
  834. X}
  835. X
  836. X/*
  837. X * Handle transactions "at top level", as Unix uucp's debug log says.
  838. X *
  839. X * As master, we scan our queues for work and send requests to the
  840. X * other side.    When done, we send a hangup request and switch to slave mode.
  841. X *
  842. X * As slave, we accept requests from the other side; when it is done,
  843. X * it sends a hangup request, and we switch to master mode, if we have
  844. X * any work queued up for that system.
  845. X *
  846. X * This repeats as long as either side has work to do.    When all the
  847. X * queued work is done, we agree to hang up, terminate the packet protocol,
  848. X * and return to the caller.  (We still haven't hung up the phone line yet.)
  849. X *
  850. X * A curious feature of the hangup protocol is that it is not a simple
  851. X * question-answer.  The master says "H", asking about hangup.  The
  852. X * slave responds "HY" saying OK.  The master then says "HY" also,
  853. X * then both of them hang up.  Maybe this is to make sure the first HY
  854. X * got ack'ed?  Anyway, an "H" is reported as HANGUP and an "HY" as
  855. X * HANGNOW.  After we send an HY, we go back to listening for commands;
  856. X * if the master sends something other than HY, we'll do it.
  857. X */
  858. X
  859. X#define HANGUP    2        /* Signal to switch master/slave roles */
  860. X#define HANGNOW 3        /* Signal to hang up now */
  861. X#define COPYFAIL    4    /* File copy failed */
  862. X
  863. Xint
  864. Xtop_level(master_mode)
  865. Xint master_mode;
  866. X{
  867. X    static char    buf[MAXMSGLEN];    /* For hangup responses */
  868. X
  869. X
  870. X    if (master_mode) {
  871. X    (void) work_scan(host_name);    /* Kick off queue scan */
  872. X    goto master;
  873. X    }
  874. X
  875. X    for (;;) {
  876. X    slave:            /*  SLAVE SIDE    */
  877. X    for (;;) {
  878. X        DEBUG(4, "*** TOP *** - slave\n", 0);
  879. X        switch (do_one_slave()) {
  880. X        case SUCCESS:
  881. X        break;
  882. X        case FAIL:
  883. X        return FAIL;
  884. X        case HANGUP:
  885. X        if (work_scan(host_name)) {
  886. X            if (wrmsg("HN"))
  887. X            return FAIL;
  888. X            goto master;
  889. X        } else {
  890. X            if (wrmsg("HY"))
  891. X            return FAIL;
  892. X            break;    /*  go to master mode */
  893. X        }
  894. X        case HANGNOW:
  895. X        goto quit;
  896. X        }
  897. X    }
  898. X    master:    /*  MASTER SIDE */
  899. X    for (;;) {
  900. X        DEBUG(4, "*** TOP *** - master\n", 0);
  901. X        switch (do_one_master()) {
  902. X        case SUCCESS:
  903. X        break;
  904. X        case FAIL:
  905. X        return FAIL;
  906. X        case HANGUP:
  907. X        /* We wrote an H command, what's the resp? */
  908. X        if (rdmsg(buf, MAXMSGLEN) != SUCCESS) {
  909. X            return FAIL;
  910. X        }
  911. X        if (buf[0] != 'H')
  912. X            return FAIL;
  913. X        if (buf[1] == 'N')
  914. X            goto slave;
  915. X        else {
  916. X            /* Write the final HY */
  917. X            if (wrmsg("HY"))
  918. X            return FAIL;
  919. X            goto quit;
  920. X        }
  921. X        }
  922. X    }
  923. X    }
  924. X
  925. Xquit:
  926. X    /* Shut down the packet protocol */
  927. X
  928. X    turnoff();
  929. X
  930. X    /* Write the closing sequence */
  931. X
  932. X    twrite(msgo4, sizeof(msgo4)-1);
  933. X    (void) instr(msgi4, sizeof(msgi4)-1);
  934. X
  935. X    twrite(msgo4, sizeof(msgo4)-1);
  936. X
  937. X    strcpy(who, "-");
  938. X    ulog(-1, "OK Conversation complete");
  939. X
  940. X    return SUCCESS;   /* Go byebye */
  941. X}
  942. X
  943. X/*
  944. X * We are slave; get a command from the other side and execute it.
  945. X *
  946. X * Result is SUCCESS, FAIL, HANGUP, or HANGNOW.
  947. X */
  948. X
  949. Xint
  950. Xdo_one_slave()
  951. X{
  952. X    static char msg[MAXMSGLEN];        /* Master's message to us */
  953. X
  954. X    /* Get master's command */
  955. X    if (rdmsg(msg, MAXMSGLEN) != SUCCESS)
  956. X    return FAIL;
  957. X
  958. X    /* Print it for easy debugging */
  959. X    DEBUG(5,"\nCommand: %s\n\n", msg);
  960. X
  961. X    switch (msg[0]) {
  962. X    case 'S':
  963. X    if (msg[1] != ' ')
  964. X        break;
  965. X    return host_send_file(msg);
  966. X    case 'R':
  967. X    if (msg[1] != ' ')
  968. X        break;
  969. X    return host_receive_file(msg);
  970. X    case 'X':
  971. X    /*
  972. X     * Cause uuxqt to run (on certain files?)
  973. X     * See Protocol.doc for sketchy details.
  974. X     */
  975. X    break;
  976. X    case 'H':
  977. X    if (msg[1] == '\0') return HANGUP;
  978. X    if (msg[1] == 'Y')  return HANGNOW;
  979. X    if (msg[1] == 'N')  return SUCCESS;     /* Ignore HN to slave */
  980. X    break;
  981. X    }
  982. X
  983. X    /* Unrecognized packet from the other end */
  984. X
  985. X    DEBUG(0, "Bad control packet refused: %s\n", msg);
  986. X    if (yesno(msg[0], 0, 0))        /* FIXME: return error code */
  987. X    return FAIL;
  988. X    return SUCCESS;
  989. X}
  990. X
  991. X/*
  992. X *  Do one piece of work as master.
  993. X *
  994. X *  FIXME:  we don't handle the flags, e.g. -c, properly!
  995. X *
  996. X *  Now only dequeues queue file if all transfers were successful.
  997. X */
  998. X
  999. Xint
  1000. Xdo_one_master()
  1001. X{
  1002. X    FILE    *fd;
  1003. X    char    *sname;
  1004. X    char    cmnd[1];            /* Command character */
  1005. X    static char buf[256];
  1006. X    int     fail = SUCCESS;
  1007. X    int     failaccum = 0;
  1008. X    int     num;
  1009. X    int     delmeflag;
  1010. X    static char notify[NAMESIZE];   /* A bit large...FIXME */
  1011. X    char    *delList[16];        /* delete files list   */
  1012. X    short   di = 0;
  1013. X
  1014. X    /* FIXME: do the notify stuff */
  1015. X
  1016. X    sname = work_next();
  1017. X    if (!sname) {
  1018. X    /* No more work, time to hang up. */
  1019. X    if (wrmsg("H"))
  1020. X        return FAIL;
  1021. X    return HANGUP;
  1022. X    }
  1023. X
  1024. X    DEBUG(2, "Request file %s\n", sname);
  1025. X
  1026. X    LockFile(sname);
  1027. X
  1028. X    fd = fopen(sname, "r");
  1029. X    if (fd == NULL) {
  1030. X    UnLockFile(sname);
  1031. X    DEBUG(0, "uucico: couldn't open %s\n", sname);
  1032. X    return SUCCESS;
  1033. X    }
  1034. X
  1035. X    while (fgets(buf, sizeof buf, fd)) {
  1036. X    DEBUG(3, "Queued request: %s", buf);
  1037. X
  1038. X    if (buf[1] != ' ')
  1039. X        goto badnum;
  1040. X
  1041. X    num = sscanf(buf, "%s %s %s %s %s %s %o\n",
  1042. X        cmnd, srcnam, dstnam, who, flags, temp, &mode, notify
  1043. X    );
  1044. X
  1045. X    switch (cmnd[0]) {
  1046. X    case 'S':
  1047. X        if (num < 7 || num > 8)
  1048. X        goto badnum;
  1049. X        fail = local_send_file(buf, &delmeflag);
  1050. X        if (delmeflag) {
  1051. X        if (di == sizeof(delList)/sizeof(delList[0])) {
  1052. X            ulog(-1, "Too many source files in Cmd file! %s", sname);
  1053. X        } else {
  1054. X            delList[di] = malloc(strlen(temp) + 1);
  1055. X            strcpy(delList[di], temp);
  1056. X            ++di;
  1057. X        }
  1058. X        }
  1059. X        break;
  1060. X    case 'R':
  1061. X        if (num != 5) {
  1062. X        if (debug > 7)
  1063. X            printf("Invalid scanf %d/5 :%s:%s:%s\n", num, cmnd, srcnam, dstnam);
  1064. X        goto badnum;
  1065. X        }
  1066. X        fail = local_receive_file();
  1067. X        break;
  1068. X    default:
  1069. X    badnum:
  1070. X        DEBUG(0, "Unknown/invalid queued request: %s\n", buf);
  1071. X        ++fail;
  1072. X        break;
  1073. X    }
  1074. X    if (fail != SUCCESS)
  1075. X        ++failaccum;
  1076. X
  1077. X    /* FIXME, what does uucp do if one of N xfers fails? */
  1078. X
  1079. X    if (fail == FAIL) {
  1080. X        ulog(-1, "Error in work file %s", sname);
  1081. X        ulog(-1, "Bad line is: %s", buf);
  1082. X    }
  1083. X    }
  1084. X    fclose(fd);
  1085. X
  1086. X    /*
  1087. X     *    If we successfuly copied everything zap the queue file
  1088. X     *    and any local data files...
  1089. X     */
  1090. X
  1091. X    if (failaccum == 0) {
  1092. X    while (di) {
  1093. X        --di;
  1094. X        remove(delList[di]);
  1095. X        free(delList[di]);
  1096. X    }
  1097. X    fail = remove(sname);
  1098. X    UnLockFile(sname);
  1099. X    if (fail != 0) {
  1100. X        ulog(-1, "Unable to remove work file %s", sname);
  1101. X        DEBUG(0, "Can't remove, errno %d\n", errno);
  1102. X    } else {
  1103. X        DEBUG(4, "Removed work file %s\n", sname);
  1104. X    }
  1105. X    } else {
  1106. X    UnLockFile(sname);
  1107. X    }
  1108. X    return SUCCESS;
  1109. X}
  1110. X
  1111. X/* Send a "yes or no" packet with character 'c'. */
  1112. X
  1113. Xint
  1114. Xyesno(c, true, err)
  1115. Xchar c;
  1116. Xint true;
  1117. Xint err;
  1118. X{
  1119. X    char buf[21];
  1120. X
  1121. X    buf[0] = c;
  1122. X    buf[1] = true? 'Y': 'N';
  1123. X    buf[2] = 0;
  1124. X    if (err && !true)
  1125. X    sprintf(buf+2,"%d", err);
  1126. X
  1127. X    return wrmsg(buf);
  1128. X}
  1129. X
  1130. X/*
  1131. X *  SLAVE MODE, Master wishes to send a file to us
  1132. X *
  1133. X *  SECURITY:    If file is not in list of allowed directories
  1134. X *        disallow transfer.  UUSPOOL:   is always in the
  1135. X *        list.
  1136. X *
  1137. X *        If file is for UUSPOOL: (the current dir), disallow "C." files
  1138. X *        NOTE: success return and file redirected to T: as this can
  1139. X *        occur only if somebody purposefully is trying to break us.
  1140. X *
  1141. X *  Return 0 = success
  1142. X */
  1143. X
  1144. Xint
  1145. Xhost_send_file(msg)
  1146. Xchar  *msg;
  1147. X{
  1148. X    FILE *fddsk;            /* Disk file pointer */
  1149. X    char    cmnd[1];            /* Command character */
  1150. X    int r;
  1151. X    int nor = 0;
  1152. X
  1153. X    sscanf(msg,"%s %s %s %s %s %s %o",
  1154. X        cmnd, srcnam, dstnam, who, flags, temp, &mode);
  1155. X
  1156. X    ulog(-1, "REQUESTED %s", msg);
  1157. X    munge_filename(dstnam, dstnam);           /* Translate to local name */
  1158. X    strcpy (temp, TmpFileName(dstnam));       /* Create a handy temp file */
  1159. X
  1160. X    if (SecurityDisallow(dstnam, 'w')) {
  1161. X    ulog(-1, "REQUEST FAILED -- SECURITY");
  1162. X    if (yesno('S', 0, 4))
  1163. X        return FAIL;
  1164. X    return SUCCESS;
  1165. X    }
  1166. X    if (SecurityDisallow(dstnam, 'c') > 0) {
  1167. X    ulog(-1, "REQUEST FAILED -- SECURITY, REMOTE TRIED TO SEND");
  1168. X    ulog(-1, "US A COMMAND FILE: %s, FILE COPIED TO T:Bad-Cmd", dstnam);
  1169. X    strcpy(dstnam, "T:Bad-Cmd");
  1170. X    nor = 1;
  1171. X    }
  1172. X
  1173. X    /* FIXME: deal with file modes now that we fopen. */
  1174. X
  1175. X    LockFile(temp);
  1176. X
  1177. X    fddsk = fopen(temp, "wb" /*, mode|0600 */);
  1178. X    if (fddsk == NULL) {
  1179. X    UnLockFile(temp);
  1180. X    /* Can't open file -- send error response */
  1181. X    if (debug > 0) {
  1182. X        printf("Cannot open temp file %s (%s) for writing, errno=%d\n",
  1183. X        temp,
  1184. X        dstnam,
  1185. X        errno
  1186. X        );
  1187. X    }
  1188. X    ulog(-1, "REQUEST FAILED -- TEMP FILE");
  1189. X    if (yesno('S', 0, 4))
  1190. X        return FAIL;
  1191. X    return SUCCESS;
  1192. X    }
  1193. X
  1194. X    /* FIXME: Are the above permissions right?? */
  1195. X    /* FIXME: Should we create directories for the file? */
  1196. X
  1197. X    if (yesno('S',1, 0)) {  /* Say yes */
  1198. X    fclose(fddsk);
  1199. X    unlink(temp);
  1200. X    UnLockFile(temp);
  1201. X    return 1;
  1202. X    }
  1203. X    r = receive_file(fddsk, temp, dstnam, srcnam, nor);
  1204. X    UnLockFile(temp);
  1205. X    return(r);
  1206. X}
  1207. X
  1208. X/*
  1209. X *  SLAVE MODE, Master wants us to send a file to it
  1210. X *
  1211. X *  SECURITY:    If file is not in list of allowed directories
  1212. X *        disallow transfer.  UUSPOOL:   is always in the
  1213. X *        list.
  1214. X *
  1215. X *  0 = sucess
  1216. X */
  1217. X
  1218. Xint
  1219. Xhost_receive_file(msg)
  1220. Xchar  *msg;
  1221. X{
  1222. X    FILE *fddsk;     /* Disk file descriptor */
  1223. X    int x;
  1224. X    char    cmnd[1];            /* Command character */
  1225. X
  1226. X    ulog(-1, "REQUESTED %s", msg);
  1227. X
  1228. X    sscanf(msg,"%s %s %s",cmnd,srcnam,dstnam);
  1229. X    munge_filename(srcnam, temp);
  1230. X
  1231. X    if (SecurityDisallow(temp, 'r')) {
  1232. X    ulog(-1, "COPY FAILED -- SECURITY");
  1233. X    if (yesno('S', 0, 4))
  1234. X        return FAIL;
  1235. X    return SUCCESS;
  1236. X    }
  1237. X
  1238. X    fddsk = fopen(temp, "rb");              /* Try to open the file */
  1239. X    if (fddsk == NULL) {
  1240. X    /* File didn't open, sigh. */
  1241. X    if (debug > 0) {
  1242. X        printf("Cannot open file %s (%s) for reading, errno=%d\n",
  1243. X        temp, srcnam, errno
  1244. X        );
  1245. X    }
  1246. X    ulog(-1, "DENIED CAN'T OPEN %s", temp);
  1247. X    if (yesno('R', 0, 2))
  1248. X        return 1;
  1249. X    return 0;
  1250. X    }
  1251. X
  1252. X    if (yesno('R',1, 0)) {  /* Say yes */
  1253. X    fclose(fddsk);
  1254. X    return 1;
  1255. X    }
  1256. X
  1257. X    x = send_file(fddsk);
  1258. X
  1259. X    switch (x) {
  1260. X    default:
  1261. X    return x;
  1262. X    case COPYFAIL:
  1263. X    /* We don't care if the copy failed, since the master
  1264. X       asked for the file and knows the result. */
  1265. X    return SUCCESS;
  1266. X    }
  1267. X    return 1;
  1268. X}
  1269. X
  1270. X/*
  1271. X *  MASTER MODE, We want to send a file.
  1272. X *
  1273. X *  Return FAIL, SUCCESS, or COPYFAIL.
  1274. X *
  1275. X *  SUCCESS is returned either if the file was not found locally (local
  1276. X *  error, and the queued transfer should be flushed) or if it was moved
  1277. X *  successfully.  COPYFAIL indicates that the queued transfer should be
  1278. X *  left queued, and later retried.  FIXME, there are several failure points
  1279. X *  in the transaction (see Protocol.doc) and we need finer control here.
  1280. X */
  1281. X
  1282. Xint
  1283. Xlocal_send_file(workstr, delmeflag)
  1284. Xchar *workstr;
  1285. Xint *delmeflag;
  1286. X{
  1287. X    static char buf[MAXMSGLEN];    /* Used for both xmit and receive */
  1288. X    FILE *fddsk;        /* Disk file descriptor */
  1289. X    int res;            /* Result and file removal status */
  1290. X
  1291. X    *delmeflag = 0;
  1292. X
  1293. X    /* WHY are temp and srcnam switched?  FIXME!  And no notify? */
  1294. X
  1295. X    sprintf(buf,"S %s %s %s %s %s 0%o %s",
  1296. X    temp, dstnam, who, flags, srcnam, mode, who
  1297. X    );
  1298. X
  1299. X    ulog(-1, "REQUEST %s", buf);
  1300. X
  1301. X    if (strchr(flags, 'c')) {
  1302. X    munge_filename(srcnam, temp);
  1303. X    } else {
  1304. X    munge_filename(temp, temp);
  1305. X    }
  1306. X    LockFile(temp);
  1307. X    fddsk = fopen(temp, "rb");
  1308. X    if (fddsk == NULL) {
  1309. X    UnLockFile(temp);
  1310. X    /* FIXME -- handle queued request for nonexistent file */
  1311. X    if (debug > 0)
  1312. X        printf("Can't open file %s (%s), errno=%d\n",
  1313. X        temp,
  1314. X        srcnam,
  1315. X        errno
  1316. X        );
  1317. X    ulog(-1, "NOT FOUND %s", temp);
  1318. X    /* return COPYFAIL;*/
  1319. X    return SUCCESS;     /*    assume file previously sent */
  1320. X    }
  1321. X
  1322. X    /* Tell the other side we want to send this file */
  1323. X
  1324. X    if (wrmsg(buf) != SUCCESS) {
  1325. X    DEBUG(0, "problem sending request\n", 0);
  1326. X    fclose(fddsk);
  1327. X    UnLockFile(temp);
  1328. X    return FAIL;
  1329. X    }
  1330. X
  1331. X    /* See what they have to say about it */
  1332. X
  1333. X    if (rdmsg(buf, MAXMSGLEN) != SUCCESS) {
  1334. X    fclose(fddsk);
  1335. X    UnLockFile(temp);
  1336. X    return FAIL;
  1337. X    }
  1338. X    if ((buf[0] != 'S') || (buf[1] != 'Y')) {
  1339. X    ulog(-1, "REQUEST DENIED %s", buf);
  1340. X    fclose(fddsk);
  1341. X    UnLockFile(temp);
  1342. X    return FAIL;
  1343. X    }
  1344. X    res = send_file(fddsk); /* FAIL, SUCCESS, or COPYFAIL */
  1345. X
  1346. X    /* Delete the source file if it was just a copy */
  1347. X
  1348. X    if (res != SUCCESS) {
  1349. X    UnLockFile(temp);
  1350. X    return res;
  1351. X    }
  1352. X    if (strchr(flags, 'c')) {   /* If copied direct from source */
  1353. X    UnLockFile(temp);
  1354. X    return res;        /* ...just return. */
  1355. X    }
  1356. X    *delmeflag = 1;
  1357. X    UnLockFile(temp);
  1358. X
  1359. X    return res;
  1360. X}
  1361. X
  1362. X/*
  1363. X *  MASTER MODE, We wish to receive a specific file so we ask for it
  1364. X *
  1365. X *  Return 0 = success
  1366. X */
  1367. X
  1368. Xint
  1369. Xlocal_receive_file()
  1370. X{
  1371. X    static char buf[MAXMSGLEN];
  1372. X    FILE *fddsk;            /* Disk file pointer */
  1373. X    int r;
  1374. X
  1375. X    /* FIXME, test dest file access before we ask for it. */
  1376. X
  1377. X    sprintf(buf,"R %s %s %s %s %s 0%o %s",
  1378. X    srcnam, dstnam, who, flags, temp, mode, who
  1379. X    );
  1380. X
  1381. X    munge_filename(dstnam, dstnam);           /* tlate to local name      */
  1382. X    strcpy (temp, TmpFileName(dstnam));       /* Create a handy temp file */
  1383. X
  1384. X    /* FIXME: deal with file modes now that we fopen. */
  1385. X    /* FIXME: Are the above permissions right?? */
  1386. X    /* FIXME: Should we create directories for the file? */
  1387. X
  1388. X    LockFile(temp);
  1389. X    fddsk = fopen(temp, "wb" /*, mode|060 */);
  1390. X
  1391. X    if (fddsk == NULL) {
  1392. X    UnLockFile(temp);
  1393. X    /* Can't open temp file -- send error response */
  1394. X    if (debug > 0) {
  1395. X        printf("Cannot open temp file %s (%s) for writing, errno=%d\n",
  1396. X        temp,
  1397. X        dstnam,
  1398. X        errno
  1399. X        );
  1400. X    }
  1401. X    ulog(-1, "REQUEST FAILED -- TEMPFILE");
  1402. X    return FAIL;
  1403. X    }
  1404. X
  1405. X    ulog(-1, "REQUEST %s", buf);
  1406. X    if (wrmsg(buf) != SUCCESS) {
  1407. X    fclose(fddsk);
  1408. X    UnLockFile(temp);
  1409. X    printf("uucico: problem sending request\n");
  1410. X    return FAIL;
  1411. X    }
  1412. X
  1413. X    /* See what the other side has to say about it */
  1414. X
  1415. X    if (rdmsg(buf, MAXMSGLEN) != SUCCESS) {
  1416. X    fclose(fddsk);
  1417. X    UnLockFile(temp);
  1418. X    return FAIL;
  1419. X    }
  1420. X    if ((buf[0] != 'R') || (buf[1] != 'Y')) {
  1421. X    ulog(-1, "REQUEST DENIED %s", buf);
  1422. X    fclose(fddsk);
  1423. X    UnLockFile(temp);
  1424. X    return SUCCESS; /* FIXME, should do something more here */
  1425. X    }
  1426. X
  1427. X    r = receive_file(fddsk, temp, dstnam, srcnam, 0);
  1428. X    UnLockFile(temp);
  1429. X    return(r);
  1430. X}
  1431. X
  1432. X/*
  1433. X *  General receive file
  1434. X */
  1435. X
  1436. Xint
  1437. Xreceive_file(fddsk, temp, dstnam, srcnam, norename)
  1438. XFILE *fddsk;
  1439. Xchar    *temp, *dstnam, *srcnam;
  1440. X{
  1441. X    int status;
  1442. X    int error = 0;            /* No errors so far */
  1443. X
  1444. X    if (rddata(fddsk) != SUCCESS)
  1445. X    error++;
  1446. X    status = fclose(fddsk);         /* Make sure the data got here */
  1447. X    if (status != 0) {
  1448. X    error++;
  1449. X    DEBUG(0, "fclose errno=%d\n", errno);
  1450. X    }
  1451. X
  1452. X    /*
  1453. X     *    Move the file from its temp location to its real location,
  1454. X     *    This needs to be able to copy a file if a simple rename
  1455. X     *    does not suffice.  Should create directories if necesary.
  1456. X     *    should use source ]name if target is a directory (i.e. no
  1457. X     *    target source name
  1458. X     */
  1459. X
  1460. X    unlink(dstnam);
  1461. X
  1462. X    if (norename)       /*  for security redirect   */
  1463. X    status = 0;
  1464. X    else
  1465. X    status = rename(temp, dstnam);
  1466. X
  1467. X    if (status != 0) {
  1468. X    error++;
  1469. X    if (debug > 0) {
  1470. X        printf("Cannot rename file %s to %s, errno=%d\n",
  1471. X        temp, dstnam, errno);
  1472. X    }
  1473. X    }
  1474. X
  1475. X    ulog(-1, "COPY %s", error ? "FAILED": "SUCCEEDED");
  1476. X
  1477. X    if (yesno('C', error == 0, 5))  /* Send yes or no */
  1478. X    return FAIL;
  1479. X
  1480. X    return SUCCESS;
  1481. X}
  1482. X
  1483. X/*
  1484. X * general file send routine
  1485. X * Return SUCCESS, FAIL, or COPYFAIL.
  1486. X */
  1487. X
  1488. Xint
  1489. Xsend_file(fddsk)
  1490. XFILE *fddsk;     /* Disk file pointer */
  1491. X{
  1492. X    static char ansbuf[MAXMSGLEN];
  1493. X
  1494. X    if (wrdata(fddsk) != SUCCESS) {
  1495. X    fclose(fddsk);
  1496. X    return COPYFAIL;
  1497. X    }
  1498. X    fclose(fddsk);
  1499. X
  1500. X    /* Await the "CY" or "CNddd" packet, and toss it. */
  1501. X
  1502. X    while (1) {
  1503. X    if (rdmsg(ansbuf, MAXMSGLEN) != SUCCESS)
  1504. X        return COPYFAIL;
  1505. X    if (ansbuf[0] != 'C') {
  1506. X        DEBUG(0,"\nDidn't get 'CY' or 'CN', got %s\n", ansbuf);
  1507. X        /* and loop looking for C message */
  1508. X    } else if (ansbuf[1] == 'Y') {
  1509. X        ulog(-1, "REQUESTED %s", ansbuf);
  1510. X        return SUCCESS;
  1511. X    } else {
  1512. X        ulog(-1, "COPY FAILED %s", ansbuf);
  1513. X        return COPYFAIL;
  1514. X    }
  1515. X    }
  1516. X    return COPYFAIL;
  1517. X}
  1518. X
  1519. END_OF_FILE
  1520. if test 33705 -ne `wc -c <'uucp2/src/uucico/uucico.c'`; then
  1521.     echo shar: \"'uucp2/src/uucico/uucico.c'\" unpacked with wrong size!
  1522. fi
  1523. # end of 'uucp2/src/uucico/uucico.c'
  1524. fi
  1525. echo shar: End of archive 11 \(of 12\).
  1526. cp /dev/null ark11isdone
  1527. MISSING=""
  1528. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1529.     if test ! -f ark${I}isdone ; then
  1530.     MISSING="${MISSING} ${I}"
  1531.     fi
  1532. done
  1533. if test "${MISSING}" = "" ; then
  1534.     echo You have unpacked all 12 archives.
  1535.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1536. else
  1537.     echo You still need to unpack the following archives:
  1538.     echo "        " ${MISSING}
  1539. fi
  1540. ##  End of shell archive.
  1541. exit 0
  1542. -- 
  1543. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  1544. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  1545. Post requests for sources, and general discussion to comp.sys.amiga.
  1546.